package com.umgsai.wx.backend.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
//import com.dianping.cat.Cat;
//import com.dianping.cat.message.Transaction;
import com.github.shyiko.mysql.binlog.BinaryLogClient;
import com.github.shyiko.mysql.binlog.event.*;
import com.google.common.collect.Maps;
import com.umgsai.wx.backend.dao.ColumnsMapper;
import com.umgsai.wx.backend.dao.data.ColumnsDO;
import com.umgsai.wx.backend.util.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
@Component
public class CommandLineRunnerImpl implements CommandLineRunner {

    @Value("${spring.datasource.host}")
    private String dbHost;
    @Value("${spring.datasource.port}")
    private int dbPort;
    @Value("${spring.datasource.databaseName}")
    private String databaseName;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("#{'${binlog.table.names}'.split(',')}")
    private Set<String> binlogTableNames;
    @Resource
    private ColumnsMapper columnsMapper;

    @Override
    public void run(String... args) throws Exception {
//        Cat.initialize();
//
//        log.info(JSON.toJSONString(System.getenv()));
//
//        Transaction t = Cat.newTransaction("URL", "pageName");
//
//        try {
//            Cat.logEvent("URL.Server", "serverIp", "SUCCESS", "ip=${serverIp}");
//            Cat.logMetricForCount("metric.key");
//            Cat.logMetricForDuration("metric.key", 5);
//
////            yourBusiness();
//
//            t.setStatus(Transaction.SUCCESS);
//        } catch (Exception e) {
//            t.setStatus(e);
//            Cat.logError(e);
//        } finally {
//            t.complete();
//        }

        if (true) {
            return;
        }

        String url = "https://api.ihuoyou001.com/api/addorder?main_body_id=2&goods_id=1531&sku_ids=3467&buynum=1&name=%E9%A9%AC%E5%8B%92%E6%88%88%E5%A3%81&phone=13003200203&regionName=%E5%8C%97%E4%BA%AC%E5%B8%82%20%E5%B8%82%E8%BE%96%E5%8C%BA%20%E4%B8%9C%E5%9F%8E%E5%8C%BA&address=%E9%A9%AC%E5%8B%92%E6%88%88%E5%A3%81%E9%A9%AC%E5%8B%92%E6%88%88%E5%A3%81%E9%A9%AC%E5%8B%92%E6%88%88%E5%A3%81%E9%A9%AC%E5%8B%92%E6%88%88%E5%A3%81&channel_code=1529";

        String body = "{\"productId\":\"17757\",\"productSpecId\":293800,\"activityType\":\"CASH_SCORE\",\"createType\":\"H5NORMAL\",\"specialId\":null,\"scene\":\"\",\"tel\":\"18817520160\",\"userName\":\"麻辣隔壁\",\"address\":\"麻辣隔壁\",\"province\":\"上海市\",\"city\":\"上海市\",\"area\":\"黄埔区\"}";
        Map<String, String> headerMap = Maps.newHashMap();
        headerMap.put("authority", "h5api.lickeji.com");
        headerMap.put("method", "POST");
        headerMap.put("path", "/mall/order/h5CreateOrder");
        headerMap.put("scheme", "https");
        headerMap.put("accept", "application/json, text/javascript, */*; q=0.01");
        headerMap.put("accept-encoding", "gzip");
        headerMap.put("accept-language", "zh-CN,zh;q=0.9");
        headerMap.put("channel", "lickeji");
        headerMap.put("content-length", "249");
        headerMap.put("content-type", "application/json;charset=UTF-8");
        headerMap.put("contenttype", "json");
        headerMap.put("dnt", "1");
        headerMap.put("domainurl", "https");
        headerMap.put("origin", "https");
        headerMap.put("referer", "https");
        headerMap.put("sec-fetch-dest", "empty");
        headerMap.put("sec-fetch-mode", "cors");
        headerMap.put("sec-fetch-site", "cross-site");
        headerMap.put("sign", "f21bd1fc5d61aa66a34f9bb7611022ed");
        headerMap.put("source", "h5");
        headerMap.put("sourceplatform", "huiyuan");
        headerMap.put("timestamp", "1682518999685");
        headerMap.put("Token", "CJY8ZGSC6prxpPdcQ3s4HtZ5YEBXMbic");
        headerMap.put("user-agent", "Mozilla/5.0");
        headerMap.put("uuid", "be268f87-7149-0fd5-6c6e-b3e0378deb96");

        Map<String, Object> paramMap = Maps.newHashMap();
        JSONObject jsonObject = JSON.parseObject(body);
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            paramMap.put(entry.getKey(), entry.getValue());
        }

        AtomicLong atomicLong = new AtomicLong(0);
        for (int i = 0; i < 100; i++) {

            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 10000000; j++) {
                        long incrementAndGet = atomicLong.incrementAndGet();
                        try {
                            String s = HttpUtil.post(url,
                                    paramMap,
                                    headerMap);
                            log.info("{} {}", incrementAndGet, s);
                            TimeUnit.MILLISECONDS.sleep(100);
                        } catch (Exception e) {
                            log.error("exception", e);
                        }
                    }
                }
            }).start();
        }

        String queryUrl = "https://api.ihuoyou001.com/api/orderList?page=1&pageSize=100";
        String result = HttpUtil.post(queryUrl,
                paramMap,
                headerMap);

        if (true) {
            return;
        }

        BinaryLogClient client = new BinaryLogClient(dbHost, dbPort, username, password);
        client.setServerId(2);

        Map<String, Map<Long, String>> tableNameColumnMap = Maps.newLinkedHashMap();
        Map<Long, Map<Long, String>> tableIdColumnMap = Maps.newLinkedHashMap();

        for (String binlogTableName : binlogTableNames) {
            tableNameColumnMap.put(binlogTableName, Maps.newLinkedHashMap());
            List<ColumnsDO> columnsDOS = columnsMapper.queryList(databaseName, binlogTableName);
            for (ColumnsDO columnsDO : columnsDOS) {
                tableNameColumnMap.get(binlogTableName).put(columnsDO.getOrdinalPosition() - 1, columnsDO.getColumnName());
            }
        }

        client.registerEventListener(event -> {
            EventData eventData = event.getData();
            if (eventData instanceof TableMapEventData) {
                TableMapEventData tableMapEventData = (TableMapEventData) eventData;
                String tableName = tableMapEventData.getTable();
                if (binlogTableNames.contains(tableName)) {
                    tableIdColumnMap.put(tableMapEventData.getTableId(), tableNameColumnMap.get(tableName));
                }
            }
            if (eventData instanceof UpdateRowsEventData) {
                UpdateRowsEventData updateRowsEventData = (UpdateRowsEventData) eventData;
                long tableId = updateRowsEventData.getTableId();
                Map<Long, String> columnMap = tableIdColumnMap.get(tableId);
                if (columnMap == null) {
                    return;
                }
                for (Map.Entry<Serializable[], Serializable[]> row : updateRowsEventData.getRows()) {
                    Serializable[] before = row.getKey();
                    Serializable[] after = row.getValue();

                    Map<String, Object> beforeMap = Maps.newLinkedHashMap();
                    Map<String, Object> afterMap = Maps.newLinkedHashMap();

                    for (int i = 0; i < before.length; i++) {
                        beforeMap.put(columnMap.get((long) i), before[i]);
                        afterMap.put(columnMap.get((long) i), after[i]);
                    }

                    log.info("beforeMap={}", JSON.toJSONString(beforeMap));
                    log.info("afterMap={}", JSON.toJSONString(afterMap));
                }
            } else if (eventData instanceof WriteRowsEventData) {
                WriteRowsEventData writeRowsEventData = (WriteRowsEventData) eventData;
                long tableId = writeRowsEventData.getTableId();
                Map<Long, String> columnMap = tableIdColumnMap.get(tableId);
                if (columnMap == null) {
                    return;
                }
                List<Serializable[]> rows = writeRowsEventData.getRows();
                Map<String, Object> afterMap = Maps.newLinkedHashMap();
                for (Serializable[] row : rows) {
                    for (int i = 0; i < row.length; i++) {
                        afterMap.put(columnMap.get((long) i), row[i]);
                    }
                    log.info("afterMap={}", JSON.toJSONString(afterMap));
                }
            } else if (eventData instanceof DeleteRowsEventData) {
                DeleteRowsEventData deleteRowsEventData = (DeleteRowsEventData) eventData;
                long tableId = deleteRowsEventData.getTableId();
                Map<Long, String> columnMap = tableIdColumnMap.get(tableId);
                if (columnMap == null) {
                    return;
                }
                List<Serializable[]> rows = deleteRowsEventData.getRows();
                Map<String, Object> beforeMap = Maps.newLinkedHashMap();
                for (Serializable[] row : rows) {
                    for (int i = 0; i < row.length; i++) {
                        beforeMap.put(columnMap.get((long) i), row[i]);
                    }
                    log.info("beforeMap={}", JSON.toJSONString(beforeMap));
                }
            } else {
                System.out.println(eventData.getClass().getName());
                System.out.println(eventData.toString());
            }
        });

        try {
            client.connect();
        } catch (IOException e) {
            log.error("client.connect error.", e);
        }
    }
}
